﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using TMPro;

public class ScrollViewController : MonoBehaviour
{
    public ScrollRect scrollRect;
    public GameObject itemPrefab;
    public Transform contentParent;
    public RectTransform viewport;
    public RectTransform centerMarker;
    public InfoPanel infoPanel;
    public TMP_InputField searchInput;

    private List<SelectableItem> items = new List<SelectableItem>();
    private List<int> filteredIndices = new List<int>();
    private int currentSelectedIndex = -1;
    private Coroutine updateInfoCoroutine;
    private bool isUserInputActive = false;
    private float inputDebounceTime = 0.3f;
    private Coroutine inputFilterCoroutine;
    private string lastAppliedKeyword = "";

    public ContentSizeFitter contentFitter;
    public VerticalLayoutGroup layoutGroup;

    void Start()
    {
        // 初始化筛选为全部
        for (int i = 0; i < MusicInfoLoader.musicInfoList.Count; i++)
        {
            filteredIndices.Add(i);
        }

        PopulateItemsWithFilter();
        scrollRect.onValueChanged.AddListener(OnScroll);

        // 输入监听改为 TMP 版本
        searchInput.onValueChanged.AddListener(OnSearchValueChanged);
        searchInput.onSelect.AddListener((_) => isUserInputActive = true);
        searchInput.onDeselect.AddListener((_) => isUserInputActive = false);

        StartCoroutine(RestoreLastSelection());
    }

    IEnumerator RestoreLastSelection()
    {
        yield return null; // 等待一帧，确保 content 布局完毕

        int savedIndex = PlayerPrefs.GetInt("LastSelectedMusicIndex", 0);
        int targetFilteredIndex = filteredIndices.IndexOf(savedIndex);
        if (targetFilteredIndex == -1 && filteredIndices.Count > 0)
        {
            targetFilteredIndex = 0;
        }

        if (targetFilteredIndex >= 0 && targetFilteredIndex < items.Count)
        {
            currentSelectedIndex = targetFilteredIndex;
            UpdateItemVisuals();
            infoPanel.UpdateInfo(MusicInfoLoader.musicInfoList[items[currentSelectedIndex].Index]);

            yield return StartCoroutine(SmoothScrollToCenter(items[currentSelectedIndex].GetComponent<RectTransform>()));
        }
    }

    void OnSearchValueChanged(string keyword)
    {
        if (inputFilterCoroutine != null)
            StopCoroutine(inputFilterCoroutine);
        inputFilterCoroutine = StartCoroutine(DelayedApplyFilter(keyword));
    }

    IEnumerator DelayedApplyFilter(string keyword)
    {
        yield return new WaitForSeconds(inputDebounceTime);

        ApplySearchFilter(keyword); 
    }

    void ApplySearchFilter(string keyword)
    {
        keyword = keyword.ToLower().Trim();
        if (keyword == lastAppliedKeyword) return;
        lastAppliedKeyword = keyword;

        filteredIndices.Clear();

        for (int i = 0; i < MusicInfoLoader.musicInfoList.Count; i++)
        {
            string title = MusicInfoLoader.musicInfoList[i].musicTitle.ToLower();
            if (title.Contains(keyword))
            {
                filteredIndices.Add(i);
            }
        }

        PopulateItemsWithFilter();
    }


    void PopulateItemsWithFilter()
    {
        // 暂停 Layout 组件更新，提高生成效率
        if (contentFitter != null) contentFitter.enabled = false;
        if (layoutGroup != null) layoutGroup.enabled = false;

        foreach (Transform child in contentParent)
        {
            Destroy(child.gameObject);
        }

        items.Clear();

        foreach (int i in filteredIndices)
        {
            GameObject go = Instantiate(itemPrefab, contentParent);
            SelectableItem item = go.GetComponent<SelectableItem>();
            item.SetText(MusicInfoLoader.musicInfoList[i].musicTitle);
            item.Index = i;
            item.Controller = this;
            items.Add(item);
        }

        // 启用 Layout
        if (layoutGroup != null) layoutGroup.enabled = true;
        if (contentFitter != null) contentFitter.enabled = true;
        LayoutRebuilder.ForceRebuildLayoutImmediate(contentParent.GetComponent<RectTransform>());

        currentSelectedIndex = items.Count > 0 ? 0 : -1;
        UpdateItemVisuals();

        if (items.Count > 0 && !isUserInputActive)
        {
            infoPanel.UpdateInfo(MusicInfoLoader.musicInfoList[items[0].Index]);
            StartCoroutine(SafeSmoothScrollToCenter(items[0].GetComponent<RectTransform>()));
        }
    }

    IEnumerator SafeSmoothScrollToCenter(RectTransform target)
    {
        yield return null;

        if (target == null || !target.gameObject.activeInHierarchy)
            yield break;
        if (viewport == null || centerMarker == null)
            yield break;

        Vector3 targetPos, centerPos;
        try
        {
            targetPos = viewport.InverseTransformPoint(target.position);
            centerPos = viewport.InverseTransformPoint(centerMarker.position);
        }
        catch
        {
            yield break;
        }

        float diff = targetPos.y - centerPos.y;
        Vector2 current = scrollRect.content.anchoredPosition;
        Vector2 targetAnchoredPos = current - new Vector2(0, diff);

        float t = 0f;
        while (t < 1f)
        {
            if (target == null || !target.gameObject.activeInHierarchy)
                yield break;

            t += Time.deltaTime * 3f;
            scrollRect.content.anchoredPosition = Vector2.Lerp(current, targetAnchoredPos, t);
            yield return null;
        }

        scrollRect.content.anchoredPosition = targetAnchoredPos;
    }


    void OnScroll(Vector2 pos)
    {
        UpdateSelection();
    }

    void UpdateSelection()
    {
        float minDistance = float.MaxValue;
        int closestIndex = -1;

        for (int i = 0; i < items.Count; i++)
        {
            float distance = Mathf.Abs(GetDistanceToCenter(items[i].GetComponent<RectTransform>()));
            if (distance < minDistance)
            {
                minDistance = distance;
                closestIndex = i;
            }
        }

        if (closestIndex != currentSelectedIndex)
        {
            currentSelectedIndex = closestIndex;
            UpdateItemVisuals();

            if (updateInfoCoroutine != null)
                StopCoroutine(updateInfoCoroutine);
            updateInfoCoroutine = StartCoroutine(DelayedInfoUpdate(items[currentSelectedIndex].Index));
        }
    }

    IEnumerator DelayedInfoUpdate(int index)
    {
        yield return new WaitForSeconds(0.3f);
        if (items[currentSelectedIndex].Index == index)
        {
            PlayerPrefs.SetInt("LastSelectedMusicIndex", index);
            PlayerPrefs.Save();
            infoPanel.UpdateInfo(MusicInfoLoader.musicInfoList[index]);
        }
    }

    float GetDistanceToCenter(RectTransform item)
    {
        Vector3 itemWorldPos = item.position;
        Vector3 centerWorldPos = centerMarker.position;
        return itemWorldPos.y - centerWorldPos.y;
    }

    void UpdateItemVisuals()
    {
        for (int i = 0; i < items.Count; i++)
        {
            items[i].SetHighlighted(i == currentSelectedIndex);
        }
    }

    public void OnItemClicked(int index)
    {
        if (index < 0 || index >= items.Count)
        {
            Debug.LogWarning($"Invalid index clicked: {index}, items.Count = {items.Count}");
            return;
        }

        if (currentSelectedIndex == index)
            return;

        currentSelectedIndex = index;
        UpdateItemVisuals();

        PlayerPrefs.SetInt("LastSelectedMusicIndex", items[index].Index);
        PlayerPrefs.Save();

        StartCoroutine(ScrollAndUpdate(index));
    }

    public void OnItemClickedByMusicIndex(int musicIndex)
    {
        int visualIndex = items.FindIndex(item => item.Index == musicIndex);
        if (visualIndex == -1)
        {
            Debug.LogWarning($"Clicked musicIndex {musicIndex} not found in current items list.");
            return;
        }

        OnItemClickedByVisualIndex(visualIndex);
    }

    private void OnItemClickedByVisualIndex(int index)
    {
        if (index < 0 || index >= items.Count)
        {
            Debug.LogWarning($"Invalid visual index: {index}, items.Count = {items.Count}");
            return;
        }

        if (currentSelectedIndex == index)
            return;

        currentSelectedIndex = index;
        UpdateItemVisuals();

        PlayerPrefs.SetInt("LastSelectedMusicIndex", items[index].Index);
        PlayerPrefs.Save();

        StartCoroutine(ScrollAndUpdate(index));
    }


    IEnumerator ScrollAndUpdate(int index)
    {
        yield return StartCoroutine(SmoothScrollToCenter(items[index].GetComponent<RectTransform>()));
        yield return new WaitForSeconds(0.05f);

        infoPanel.UpdateInfo(MusicInfoLoader.musicInfoList[items[index].Index]);
    }

    IEnumerator SmoothScrollToCenter(RectTransform target)
    {
        yield return null;

        Vector3 targetPos = viewport.InverseTransformPoint(target.position);
        Vector3 centerPos = viewport.InverseTransformPoint(centerMarker.position);
        float diff = targetPos.y - centerPos.y;

        Vector2 current = scrollRect.content.anchoredPosition;
        Vector2 targetAnchoredPos = current - new Vector2(0, diff);

        float t = 0f;
        while (t < 1f)
        {
            t += Time.deltaTime * 3f;
            scrollRect.content.anchoredPosition = Vector2.Lerp(current, targetAnchoredPos, t);
            yield return null;
        }

        scrollRect.content.anchoredPosition = targetAnchoredPos;
    }
}
